package com.alex.megacj.utils;

import java.nio.ByteBuffer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair;

import com.alex.megacj.handler.RequestContext;
import com.alex.megacj.mapper.URLMapper;
import com.alex.utils.http.HttpResult;

public class PageUtils {

	private static final Pattern HREF_PATTERN = Pattern.compile("<a.+?href=[\"']([^\"']*)[\"']", Pattern.CASE_INSENSITIVE);

	private static final Pattern SCRIPT_PATTERN = Pattern.compile("<script[^>]+(.+?)</script>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

	private static final Pattern IMG_PATTERN = Pattern.compile("<(?:img|script).+?src=[\"']([^\"']+)[\"']", Pattern.CASE_INSENSITIVE);

	private static final Pattern LINK_PATTERN = Pattern.compile("<link.+?href=[\"']([^\"'>]+)[\"']", Pattern.CASE_INSENSITIVE);
	
	private static final Pattern CSS_URL_PATTERN = Pattern.compile("url\\([\"']?([^\"'\\)]+)[\"']?\\)", Pattern.CASE_INSENSITIVE);

	private static final Pattern CHARSET_PATTERN = Pattern.compile("<meta.+?charset=([^\"'>]+)", Pattern.CASE_INSENSITIVE);

	public static String replaceLinks(String page, final RequestContext context) {
		final URLMapper mapper = context.scenario.getUrlMapper();
		return RegexProcessor.process(page, HREF_PATTERN, new ReplacementHandler() {
			@Override
			public String handleReplacement(String group) {
				return mapper.replaceLink(group, context);
			}
		});
	}
	
	public static String processImages(String page, final RequestContext context) {
		final URLMapper mapper = context.scenario.getUrlMapper();
		return RegexProcessor.process(page, IMG_PATTERN, new ReplacementHandler() {
			public String handleReplacement(String src) {
				return mapper.replaceLink(src, context);
			}
		});
	}

	public static String processStyleLinks(String page, final RequestContext context) {
		final URLMapper mapper = context.scenario.getUrlMapper();
		return RegexProcessor.process(page, LINK_PATTERN, new ReplacementHandler() {
			public String handleReplacement(String href) {
				return mapper.replaceLink(href, context);
			}
		});
	}
	
	public static String processCSS(String page, final RequestContext context) {
		final URLMapper mapper = context.scenario.getUrlMapper();
		return RegexProcessor.process(page, CSS_URL_PATTERN, new ReplacementHandler() {
			public String handleReplacement(String url) {
				return mapper.replaceLink(url, context);
			}
		});
	}
	
	public static String getCharset(HttpResult httpResult, byte[] pageBytes) {
		Matcher matcher = CHARSET_PATTERN.matcher(ByteBuffer.wrap(pageBytes).asCharBuffer());
		if (matcher.find()) {
			return matcher.group(1);
		}
		
		Header header = httpResult.getResponse().getFirstHeader("content-type");
		if (header != null) {
			HeaderElement[] elements = header.getElements();
			if (elements.length > 0) {
				NameValuePair param = elements[0].getParameterByName("charset");
				if (param != null) {
					return param.getValue();
				}
			}
		}
		
		return "iso8859-1";
	}

	public static String deleteScripts(String page) {
		return SCRIPT_PATTERN.matcher(page).replaceAll("");
	}
}
